/*
 * JGO2RDF creates a RDF representation of GAF2 files, which are automatically sourced from GO ftp site.
 * Copyright (C) 2012 Matthew M. Hindle & Artem Lysenko
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package uk.co.jgo2rdf.goa.model;

import uk.co.jgo2rdf.exception.ValueNotSetException;
import uk.co.jgo2rdf.goa.go.OntologyType;

import java.util.Date;
import java.util.Set;

/**
 * Represents a row entry in a GOA file (http://www.geneontology.org/GO.format.gaf-2_0.shtml)
 * <p/>
 * Created by IntelliJ IDEA.
 * User: hindlem
 * Date: 4/8/11
 * Time: 3:21 PM
 */
public interface GOAEntry {

    public String toString();

    public boolean equals(Object obj);

    public int hashCode();

    /**
     * DB (column 1)
     * refers to the database from which the identifier in DB object ID (column 2) is drawn. This is not necessarily the group submitting the file. If a UniProtKB ID is the DB object ID (column 2), DB (column 1) should be UniProtKB.
     * must be one of the values from the set of GO database cross-references
     * this field is mandatory, cardinality 1
     *
     * @return the database from which the identifier in DB object ID comes
     */
    public String getDB() throws ValueNotSetException;

    /**
     * DB Object ID (column 2)
     * a unique identifier from the database in DB (column 1) for the item being annotated
     * this field is mandatory, cardinality 1
     * In GAF 2.0 format, the identifier must reference a top-level primary gene or gene product identifier: either a gene, or a protein that has a 1:1 correspondence to a gene. Identifiers referring to particular protein isoforms or post-translationally cleaved or modified proteins are not legal values in this field.
     * The DB object ID (column 2) is the identifier for the database object, which may or may not correspond exactly to what is described in a paper. For example, a paper describing a protein may support annotations to the gene encoding the protein (gene ID in DB object ID field) or annotations to a protein object (protein ID in DB object ID field).
     *
     * @return a unique identifier from the database in DB
     */
    public String getDBObject_ID() throws ValueNotSetException;

    /**
     * DB Object Symbol (column 3)
     * a (unique and valid) symbol to which DB object ID is matched
     * can use ORF name for otherwise unnamed gene or protein
     * if gene products are annotated, can use gene product symbol if available, or many gene product annotation entries can share a gene symbol
     * this field is mandatory, cardinality 1
     * The DB Object Symbol field should be a symbol that means something to a biologist wherever possible (a gene symbol, for example). It is not an ID or an accession number (DB object ID [column 2] provides the unique identifier), although IDs can be used as a DB object symbol if there is no more biologically meaningful symbol available (e.g., when an unnamed gene is annotated).
     *
     * @return a (unique and valid) symbol to which DB object ID is matched
     */
    public String getDBObjectSymbol();

    /**
     * Qualifier (column 4)
     * flags that modify the interpretation of an annotation
     * one (or more) of NOT, contributes_to, colocalizes_with
     * this field is not mandatory; cardinality 0, 1, >1; for cardinality >1 use a pipe to separate entries (e.g. NOT|contributes_to)
     * See also the documentation on qualifiers in the GO annotation guide
     *
     * @return flags that modify the interpretation of an annotation
     */
    public String getQualifier() throws ValueNotSetException;

    /**
     * has a Qualifier set
     *
     * @return
     */
    public boolean hasQualifier();

    /**
     * GO ID (column 5)
     * the GO identifier for the term attributed to the DB object ID
     * this field is mandatory, cardinality 1
     *
     * @return has flags that modify the default interpretation of an annotation
     */
    public String getGO_ID_String() throws ValueNotSetException;

    /**
     * GO ID (column 5) as an integer
     * the GO identifier for the term attributed to the DB object ID
     * this field is mandatory, cardinality 1
     *
     * @return has flags that modify the default interpretation of an annotation
     */
    public int getGO_ID() throws ValueNotSetException;

    /**
     * DB:Reference (column 6)
     * one or more unique identifiers for a single source cited as an authority for the attribution of the GO ID to the DB object ID. This may be a literature reference or a database record. The syntax is DB:accession_number.
     * Note that only one reference can be cited on a single line in the gene association file. If a reference has identifiers in more than one database, multiple identifiers for that reference can be included on a single line. For example, if the reference is a published paper that has a PubMed ID, we strongly recommend that the PubMed ID be included, as well as an identifier within a model organism database. Note that if the model organism database has an identifier for the reference, that identifier should always be included, even if a PubMed ID is also used.
     * this field is mandatory, cardinality 1, >1; for cardinality >1 use a pipe to separate entries (e.g. SGD_REF:S000047763|PMID:2676709).
     *
     * @return one or more unique identifiers for a single source
     */
    public Set<String[]> getDB_References() throws ValueNotSetException;

    /**
     * @return
     */
    public String getEvidenceCode() throws ValueNotSetException;

    /**
     * Evidence Code (column 7)
     * see the GO evidence code guide for the list of valid evidence codes for GO annotations
     * this field is mandatory, cardinality 1
     *
     * @return the GO evidence code
     */
    public String getWithFrom() throws ValueNotSetException;

    /**
     * With [or] From (column 8)
     * Also referred to as with, from or the with/from column
     * one of:
     * <p/>
     * DB:gene_symbol
     * DB:gene_symbol[allele_symbol]
     * DB:gene_id
     * DB:protein_name
     * DB:sequence_id
     * GO:GO_id
     * CHEBI:CHEBI_id
     * <p/>
     * this field is not mandatory overall, but is required for some evidence codes (see below and the evidence code documentation for details); cardinality 0, 1, >1; for cardinality >1 use a pipe to separate entries (e.g. CGSC:pabA|CGSC:pabB)
     *
     * @return with/from
     */
    public boolean hasWithFrom();

    /**
     * Aspect (column 9)
     * refers to the namespace or ontology to which the GO ID (column 5) belongs; one of P (biological process), F (molecular function) or C (cellular component)
     * this field is mandatory; cardinality 1
     *
     * @return refers to the namespace or ontology to which the GO ID is a memeber
     */
    public OntologyType getAspect() throws ValueNotSetException;

    /**
     * DB Object Name (column 10)
     * name of gene or gene product
     * this field is not mandatory, cardinality 0, 1 [white space allowed]
     *
     * @return name of gene or gene product
     */
    public String getDBObjectName() throws ValueNotSetException;

    /**
     * @return
     */
    public boolean hasDBObjectName();

    /**
     * DB Object Synonym (column 11)
     * Gene symbol [or other text]
     * Note that we strongly recommend that gene synonyms are included in the gene association file, as this aids the searching of GO.
     * this field is not mandatory, cardinality 0, 1, >1 [white space allowed]; for cardinality >1 use a pipe to separate entries (e.g. YFL039C|ABY1|END7|actin gene)
     *
     * @return Gene symbol
     */
    public String getDBObjectSynonym() throws ValueNotSetException;

    /**
     * @return
     */
    public boolean hasDBObjectSynonym();

    /**
     * DB Object Type (column 12)
     * A description of the type of gene product being annotated. If a gene product form ID (column 17) is supplied, the DB object type will refer to that entity; if no gene product form ID is present, it will refer to the entity that the DB object symbol (column 2) is believed to produce and which actively carries out the function or localization described.
     * one of the following: protein_complex; protein; transcript; ncRNA; rRNA; tRNA; snRNA; snoRNA; any subtype of ncRNA in the Sequence Ontology. If the precise product type is unknown, gene_product should be used.
     * this field is mandatory, cardinality 1
     * The object type (gene_product, transcript, protein, protein_complex, etc.) listed in the DB object type field must match the database entry identified by the gene product form ID, or, if this is absent, the expected product of the DB object ID. Note that DB object type refers to the database entry (i.e. it represents a protein, functional RNA, etc.); this column does not reflect anything about the GO term or the evidence on which the annotation is based. For example, if your database entry represents a protein-encoding gene, then protein goes in the DB object type column. The text entered in the DB object name and DB object symbol should refer to the entity in DB object ID. For example, several alternative transcripts from one gene may be annotated separately, each with the same gene ID in DB object ID, and specific gene product identifiers in gene product form ID, but list the same gene symbol in the DB object symbol column.
     *
     * @return A description of the type of gene product being annotated
     */
    public String getDBObjectType() throws ValueNotSetException;

    /**
     * TAXONS must be sorted for comparison reasons!!!
     * Taxon (column 13)
     * taxonomic identifier(s)
     * For cardinality 1, the ID of the species encoding the gene product.
     * For cardinality 2, to be used only in conjunction with terms that have the biological process term multi-organism process or the cellular component term host cell as an ancestor. The first taxon ID should be that of the organism encoding the gene or gene product, and the taxon ID after the pipe should be that of the other organism in the interaction.
     * this field is mandatory, cardinality 1, 2; for cardinality 2 use a pipe to separate entries (e.g. taxon:1|taxon:1000)
     * See the GO annotation conventions for more information on multi-organism terms.
     *
     * @return NCBI tax ids for the species the gene/protein is located in
     */
    public int[] getTaxons() throws ValueNotSetException;

    /**
     * Date (column 14)
     * Date on which the annotation was made; format is YYYYMMDD
     * this field is mandatory, cardinality 1
     *
     * @return Date on which the annotation was made
     */
    public Date getDate() throws ValueNotSetException;

    /**
     * Assigned By (column 15)
     * The database which made the annotation
     * one of the values from the set of GO database cross-references
     * Used for tracking the source of an individual annotation.
     * Default value is value entered as the DB (column 1).
     * Value will differ from column 1 for any annotation that is made by one database and incorporated into another.
     * this field is mandatory, cardinality 1
     *
     * @return the database which made the annotation
     */
    public String getAssignedBy() throws ValueNotSetException;

    /**
     * @return has an identified database which made the annotation
     */
    public boolean hasAssigned_By();

    /**
     * Annotation Extension (column 16)
     * one of:
     * <p/>
     * DB:gene_id
     * DB:sequence_id
     * CHEBI:CHEBI_id
     * Cell Type Ontology:CL_id
     * GO:GO_id
     * <p/>
     * Contains cross references to other ontologies that can be used to qualify or enhance the annotation. The cross-reference is prefaced by an appropriate GO relationship; references to multiple ontologies can be entered. For example, if a gene product is localized to the mitochondria of lymphocytes, the GO ID (column 5) would be mitochondrion ; GO:0005439, and the annotation extension column would contain a cross-reference to the term lymphocyte from the Cell Type Ontology.
     *
     * @return Contains cross references to other ontologies
     */
    public String getAnnotation_Extension() throws ValueNotSetException;

    /**
     * @return has cross references to other ontologies?
     */
    public boolean hasAnnotation_Extension();

    /**
     * Gene Product Form ID (column 17)
     * As the DB Object ID (column 2) entry must be a canonical entity—a gene OR an abstract protein that has a 1:1 correspondence to a gene—this field allows the annotation of specific variants of that gene or gene product. Contents will frequently include protein sequence identifiers: for example, identifiers that specify distinct proteins produced by to differential splicing, alternative translational starts, post-translational cleavage or post-translational modification. Identifiers for functional RNAs can also be included in this column.
     * The identifier used must be a standard 2-part global identifier, e.g. UniProtKB:OK0206-2
     * <p/>
     * When the gene product form ID (column 17) is filled with a protein identifier, the value in DB object type (column 12) must be protein. Protein identifiers can include UniProtKB accession numbers, NCBI NP identifiers or Protein Ontology (PRO) identifiers.
     * When the gene product form ID (column 17) is filled with a functional RNA identifier, the DB object type (column 12) must be either ncRNA, rRNA, tRNA, snRNA, or snoRNA.
     * <p/>
     * This column may be left blank; if so, the value in DB object type (column 12) will provide a description of the expected gene product.
     *
     * @return he identifier used must be a standard 2-part global identifier, e.g. UniProtKB:OK0206-2
     */
    public String getGeneProductFormID() throws ValueNotSetException;

    /**
     * @return has an gene product form id
     */
    public boolean hasGeneProductFormID();

}
